﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MSCISDevMetricHelper;
using System.IO;
using Microsoft.File.Adapter;
using System.Threading;


namespace MSCISDevMetricServer
{
    public class MetricServer
    {
        DataTable dtProjectList = null;
        static AutoResetEvent waitCheckBugs = new AutoResetEvent(false);
        string BugListFile = CommonHelper.GetConfigValue("BugListFile");
        string TestCaseListFile = CommonHelper.GetConfigValue("TestCaseListFile");
        string TaskListFile = CommonHelper.GetConfigValue("TaskListFile");

        string ConnectionString
        {
            get {
                return SqlHelper.GenerateSqlLink(CommonHelper.GetConfigValue("DBServer"), CommonHelper.GetConfigValue("DBname"));
            }
        }

        private void GetProjectList()
        {
            try
            {
                dtProjectList = SqlHelper.ExecuteDataset(ConnectionString, CommandType.Text, "SELECT Name as ProjectFriendName FROM dbo.Project").Tables[0];
            }
            catch (Exception ex)
            {
                //CommonHelper.writelog("GetProjectList Failed\r\n" + ex.ToString());
                throw new System.ArgumentException("GetProjectList Failed \r\n" + ex.ToString()); 

            }
        }

        private List<string> GetWorkItemFolderFullName()
        {
            List<string> list = new List<string>();

            //get Bug wiq folder
            DirectoryInfo wiqBugFolder = new DirectoryInfo(CommonHelper.GetConfigValue("WIQBugFolder").ToString());
            
            //get Test cases wiq folder
            DirectoryInfo wiqTestCaseFolder = new DirectoryInfo(CommonHelper.GetConfigValue("WIQTestCaseFolder").ToString());

            //get Task wiq folder
            DirectoryInfo wiqTaskFolder = new DirectoryInfo(CommonHelper.GetConfigValue("WIQTaskFolder").ToString());

            list.Add(wiqBugFolder.FullName);
            list.Add(wiqTestCaseFolder.FullName);
            list.Add(wiqTaskFolder.FullName);
            return list;
        }

        public void ProcessProjectList()
        {
            bool debug = true;

            //if (dtProjectList == null)
                GetProjectList();
            if (dtProjectList.Rows.Count < 1)
            {
                CommonHelper.writelog("No Project List in queue");
                return;
            }

            string strTFSServerProvider = "";
            string strProjectName = "";
            string strProjectFriendName = "";
            List<string> lstWorkItemFolderName = GetWorkItemFolderFullName();

            if(debug)
            {
                #region  sequential execution
                foreach (var workItemFolderFullName in lstWorkItemFolderName)
                {
                    foreach (DataRow dr in dtProjectList.Rows)
                    {
                        //strTFSServerProvider = dr["TFSServerProvider"].ToString();
                        //strProjectName = dr["ProjectName"].ToString();
                        strProjectFriendName = dr["ProjectFriendName"].ToString();

                        FileInfo fiWiq = new FileInfo(workItemFolderFullName + "\\" + strProjectFriendName + ".wiq");
                        if (!fiWiq.Exists)
                            continue;
                        try
                        {
                            if (workItemFolderFullName.IndexOf("Bugs") > 0)
                            {
                                try
                                {
                                    TFSServerProvider.TFSQueryFileProvider.GetItemFromTFSQueryFileToFile(fiWiq.FullName, BugListFile, "BugList");
                                }
                                catch (Exception ex)
                                {
                                    //CommonHelper.writelog("Download buglist for "+strProjectFriendName+" failed." + ex.ToString());
                                    throw new System.ArgumentException("ProcessProjectList-GetItemFromTFSQueryFileToFile Failed: \r\n" + ex.ToString());
                                }
                                ProcessWorkItemList(strProjectFriendName, BugListFile, "tblBugListStage");
                            }

                            if (workItemFolderFullName.IndexOf("TestCases") > 0)
                            {

                                try
                                {
                                    TFSServerProvider.TFSQueryFileProvider.GetItemFromTFSQueryFileToFile(fiWiq.FullName, TestCaseListFile, "TestCaseList");
                                }
                                catch (Exception ex)
                                {
                                    //CommonHelper.writelog("Download buglist for "+strProjectFriendName+" failed." + ex.ToString());
                                    throw new System.ArgumentException("ProcessProjectList-GetItemFromTFSQueryFileToFile Failed: \r\n" + ex.ToString());
                                }

                                ProcessWorkItemList(strProjectFriendName, TestCaseListFile, "tblTestCaseListStage");
                            }

                            if (workItemFolderFullName.IndexOf("Tasks") > 0)
                            {

                                try
                                {
                                    TFSServerProvider.TFSQueryFileProvider.GetItemFromTFSQueryFileToFile(fiWiq.FullName, TaskListFile, "TaskList");
                                }
                                catch (Exception ex)
                                {
                                    //CommonHelper.writelog("Download buglist for "+strProjectFriendName+" failed." + ex.ToString());
                                    throw new System.ArgumentException("ProcessProjectList-GetItemFromTFSQueryFileToFile Failed: \r\n" + ex.ToString());
                                }

                                ProcessWorkItemList(strProjectFriendName, TaskListFile, "tblTaskListStage");
                            }

                            WriteStatusLogToDB(strProjectFriendName, "Succeed");
                            CommonHelper.writelog("ProcessProjectList-" + strProjectFriendName + " Succeed");
                        }
                        catch (Exception ex)
                        {
                            WriteStatusLogToDB(strProjectFriendName, "Failed");
                            CommonHelper.writelog("ProcessProjectList-" + strProjectFriendName + " Failed: \r\n" + ex.ToString());
                            throw new Exception(ex.ToString());
                        }
                    }
                }
                #endregion

                #region  sequential execution 1
                //foreach (var workItemFolderFullName in lstWorkItemFolderName)
                //{
                //    if (workItemFolderFullName.IndexOf("Bugs") > 0)
                //    {
                //        foreach (DataRow dr in dtProjectList.Rows)
                //        {
                //            //strTFSServerProvider = dr["TFSServerProvider"].ToString();
                //            //strProjectName = dr["ProjectName"].ToString();
                //            strProjectFriendName = dr["ProjectFriendName"].ToString();

                //            FileInfo fiWiq = new FileInfo(workItemFolderFullName + "\\" + strProjectFriendName + ".wiq");
                //            if (!fiWiq.Exists)
                //                continue;
                //            try
                //            {
                //                try
                //                {
                //                    TFSServerProvider.TFSQueryFileProvider.GetItemFromTFSQueryFileToFile(fiWiq.FullName, BugListFile, "BugList");
                //                }
                //                catch (Exception ex)
                //                {
                //                    //CommonHelper.writelog("Download buglist for "+strProjectFriendName+" failed." + ex.ToString());
                //                    throw new System.ArgumentException("ProcessProjectList-GetItemFromTFSQueryFileToFile-Bugs Failed: \r\n" + ex.ToString());
                //                }
                //                ProcessWorkItemList(strProjectFriendName, BugListFile, "tblBugListStage");
                //            }
                //            catch (Exception ex)
                //            {
                //                WriteStatusLogToDB("[Bugs] " + strProjectFriendName, "Failed");
                //                CommonHelper.writelog("ProcessProjectList-[Bugs] " + strProjectFriendName + " Failed: \r\n" + ex.ToString());
                //            }
                //        }
                //    }
                //    else if (workItemFolderFullName.IndexOf("TestCases") > 0)
                //    {
                //        foreach (DataRow dr in dtProjectList.Rows)
                //        {
                //            //strTFSServerProvider = dr["TFSServerProvider"].ToString();
                //            //strProjectName = dr["ProjectName"].ToString();
                //            strProjectFriendName = dr["ProjectFriendName"].ToString();

                //            FileInfo fiWiq = new FileInfo(workItemFolderFullName + "\\" + strProjectFriendName + ".wiq");
                //            if (!fiWiq.Exists)
                //                continue;
                //            try
                //            {

                //                try
                //                {
                //                    TFSServerProvider.TFSQueryFileProvider.GetItemFromTFSQueryFileToFile(fiWiq.FullName, TestCaseListFile, "TestCaseList");
                //                }
                //                catch (Exception ex)
                //                {
                //                    //CommonHelper.writelog("Download buglist for "+strProjectFriendName+" failed." + ex.ToString());
                //                    throw new System.ArgumentException("ProcessProjectList-GetItemFromTFSQueryFileToFile-TestCases Failed: \r\n" + ex.ToString());
                //                }

                //                ProcessWorkItemList(strProjectFriendName, TestCaseListFile, "tblTestCaseListStage");
                //            }
                //            catch (Exception ex)
                //            {
                //                WriteStatusLogToDB("[TestCases] " + strProjectFriendName, "Failed");
                //                CommonHelper.writelog("ProcessProjectList-[TestCases] " + strProjectFriendName + " Failed: \r\n" + ex.ToString());
                //            }
                //        }
                //    }
                //    else if (workItemFolderFullName.IndexOf("Tasks") > 0)
                //    {
                //        foreach (DataRow dr in dtProjectList.Rows)
                //        {
                //            //strTFSServerProvider = dr["TFSServerProvider"].ToString();
                //            //strProjectName = dr["ProjectName"].ToString();
                //            strProjectFriendName = dr["ProjectFriendName"].ToString();

                //            FileInfo fiWiq = new FileInfo(workItemFolderFullName + "\\" + strProjectFriendName + ".wiq");
                //            if (!fiWiq.Exists)
                //                continue;
                //            try
                //            {

                //                try
                //                {
                //                    TFSServerProvider.TFSQueryFileProvider.GetItemFromTFSQueryFileToFile(fiWiq.FullName, TaskListFile, "TaskList");
                //                }
                //                catch (Exception ex)
                //                {
                //                    //CommonHelper.writelog("Download buglist for "+strProjectFriendName+" failed." + ex.ToString());
                //                    throw new System.ArgumentException("ProcessProjectList-GetItemFromTFSQueryFileToFile-Tasks Failed: \r\n" + ex.ToString());
                //                }

                //                ProcessWorkItemList(strProjectFriendName, TaskListFile, "tblTaskListStage");
                //            }
                //            catch (Exception ex)
                //            {
                //                WriteStatusLogToDB("[Tasks] " + strProjectFriendName, "Failed");
                //                CommonHelper.writelog("ProcessProjectList-[Tasks] " + strProjectFriendName + " Failed: \r\n" + ex.ToString());
                //            }
                //        }
                //    }
                //}
                #endregion 
            }else
            {
                #region  Parallel execution

                Parallel.ForEach(lstWorkItemFolderName.ToArray(), workItemFolderFullName =>
                {
                    foreach (DataRow dr in dtProjectList.Rows)
                    {
                        //strTFSServerProvider = dr["TFSServerProvider"].ToString();
                        //strProjectName = dr["ProjectName"].ToString();
                        strProjectFriendName = dr["ProjectFriendName"].ToString();

                        FileInfo fiWiq = new FileInfo(workItemFolderFullName + "\\" + strProjectFriendName + ".wiq");
                        if (!fiWiq.Exists)
                            continue;
                        try
                        {
                            if (workItemFolderFullName.IndexOf("Bugs") > 0)
                            {
                                try
                                {
                                    TFSServerProvider.TFSQueryFileProvider.GetItemFromTFSQueryFileToFile(fiWiq.FullName, BugListFile, "BugList");
                                }
                                catch (Exception ex)
                                {
                                    //CommonHelper.writelog("Download buglist for "+strProjectFriendName+" failed." + ex.ToString());
                                    throw new System.ArgumentException("ProcessProjectList-GetItemFromTFSQueryFileToFile Failed: \r\n" + ex.ToString());
                                }
                                ProcessWorkItemList(strProjectFriendName, BugListFile, "tblBugListStage");
                            }

                            if (workItemFolderFullName.IndexOf("TestCases") > 0)
                            {

                                try
                                {
                                    TFSServerProvider.TFSQueryFileProvider.GetItemFromTFSQueryFileToFile(fiWiq.FullName, TestCaseListFile, "TestCaseList");
                                }
                                catch (Exception ex)
                                {
                                    //CommonHelper.writelog("Download buglist for "+strProjectFriendName+" failed." + ex.ToString());
                                    throw new System.ArgumentException("ProcessProjectList-GetItemFromTFSQueryFileToFile Failed: \r\n" + ex.ToString());
                                }

                                ProcessWorkItemList(strProjectFriendName, TestCaseListFile, "tblTestCaseListStage");
                            }

                            if (workItemFolderFullName.IndexOf("Tasks") > 0)
                            {

                                try
                                {
                                    TFSServerProvider.TFSQueryFileProvider.GetItemFromTFSQueryFileToFile(fiWiq.FullName, TaskListFile, "TaskList");
                                }
                                catch (Exception ex)
                                {
                                    //CommonHelper.writelog("Download buglist for "+strProjectFriendName+" failed." + ex.ToString());
                                    throw new System.ArgumentException("ProcessProjectList-GetItemFromTFSQueryFileToFile Failed: \r\n" + ex.ToString());
                                }

                                ProcessWorkItemList(strProjectFriendName, TaskListFile, "tblTaskListStage");
                            }

                            WriteStatusLogToDB(strProjectFriendName, "Succeed");
                            CommonHelper.writelog("ProcessProjectList-" + strProjectFriendName + " Succeed");
                        }
                        catch (Exception ex)
                        {
                            WriteStatusLogToDB(strProjectFriendName, "Failed");
                            CommonHelper.writelog("ProcessProjectList-" + strProjectFriendName + " Failed: \r\n" + ex.ToString());
                        }
                    }

                }
                );
                #endregion
            }
        }

        private void WriteStatusLogToDB(string ProjectFriendName, string State)
        {
            try
            {
                SqlHelper.ExecuteNonQuery(ConnectionString, CommandType.Text, " EXEC spWriteLog '"+ProjectFriendName+"','"+State+"'");
            }
            catch(Exception ex)
            {
                throw new System.ArgumentException("WriteStatusLogToDB Failed: \r\n" + ex.ToString()); 
            }
        }

        public void RefreshCheck(object state, bool timedOut)
        {
            CommonHelper.writelog("Refresh Start");
                ProcessProjectList();
            //MessageBox.Show("tick");
            CommonHelper.writelog("Refresh Complete");

        }

        private void ProcessWorkItemList(string ProjectFriendName,string SourceFileFullName,string TargetStgTableName)
        {
            string xml = @"<?xml version=""1.0"" encoding=""utf-8""?>
                            <ImportFileFormat>
                            <Formats>
                            <Format Name=""T_SourceFileFullName"" Value=""" + SourceFileFullName + @"""  Required = ""Y""/>
                            <Format Name=""T_ExcelSheetNameWithArea"" Value="""" Required = ""Y""/>
                            <Format Name=""T_FileType"" Value=""txt"" Required = ""Y""/>
                            <Format Name=""T_DestinationServer"" Value=""" + CommonHelper.GetConfigValue("DBServer").ToString() + @""" Required = ""Y""/>
                            <Format Name=""T_DestinationDB"" Value=""" + CommonHelper.GetConfigValue("DBName").ToString() + @""" Required = ""Y""/>
                            <Format Name=""T_DestinationTable"" Value=""" + TargetStgTableName + @""" Required = ""Y""/>
                            <Format Name=""T_DestinationTableSchema"" Value=""dbo"" Required = ""N""/>
                            <Format Name=""T_UseFirstRowAsColumnName"" Value=""True"" Required = ""N""/>
                            <Format Name=""T_RecreateDestinationTable"" Value=""True"" Required = ""N""/>
                            <Format Name=""T_TruncateTable"" Value=""False"" Required = ""N""/>
                            <Format Name=""T_ColumnNameList"" Value="""" Required = ""N""/>
                            <Format Name=""T_CopyOrMove"" Value=""Copy"" Required = ""N""/>
                            <Format Name=""T_TimestampPostFix"" Value=""False"" Required = ""N""/>
                            <Format Name=""T_UseWorkFolder"" Value=""False"" Required = ""N""/>
                            <Format Name=""T_WorkFolderPath"" Value=""C:\FileToSQL\Process"" Required = ""N""/>
                            <Format Name=""T_UseArchiveFolder"" Value=""False"" Required = ""N""/>
                            <Format Name=""T_ArchiveFolderPath"" Value=""C:\FileToSQL\Archive"" Required = ""N""/>
                            <Format Name=""T_UseErrorFolder"" Value=""False"" Required = ""N""/>
                            <Format Name=""T_ErrorFolderPath"" Value=""C:\FileToSQL\Error"" Required = ""N""/>
                            <Format Name=""T_FlatFileDelimiter"" Value=""|~|"" Required = ""N""/>
                            <Format Name=""T_BulkInsertBatchSize"" Value="""" Required = ""N""/>
                            <Format Name=""T_BulkInsertMaxErrors"" Value=""0"" Required = ""N""/>
                            <Format Name=""T_DeleteFormatFile"" Value=""true"" Required=""N"" />
                            </Formats>
                            </ImportFileFormat>";
            try
            {
                string output = "";
                output = ClientControl.ImportFileToDatabase(xml);
                if (output.ToLower().IndexOf("error") > 0)
                {
                    //CommonHelper.writelog("Load file of " + ProjectFriendName + " Failed.\r\n" + output);
                    throw new System.ArgumentException("ProcessWorkItemList-ImportFileToDatabase failed:\r\n" + output);
                }
                else
                {
                    if (SourceFileFullName.IndexOf("Bug") > 0)
                    {
                        SqlHelper.ExecuteNonQuery(ConnectionString, CommandType.Text, "EXEC spProcessBugStage '" + ProjectFriendName + "' ");
                    }
                    else if (SourceFileFullName.IndexOf("TestCase") > 0)
                    {
                        SqlHelper.ExecuteNonQuery(ConnectionString, CommandType.Text, "EXEC spProcessTestCaseStage '" + ProjectFriendName + "' ");
                    }
                    else if (SourceFileFullName.IndexOf("Task") > 0)
                    {
                        SqlHelper.ExecuteNonQuery(ConnectionString, CommandType.Text, "EXEC spProcessTaskStage '" + ProjectFriendName + "' ");
                    }
                }
            }
            catch (Exception ex)
            {
                CommonHelper.writelog("ProcessWorkItemList " + ProjectFriendName + " Failed.\r\n" + ex.ToString());
                throw new System.ArgumentException(ex.ToString());
            }
        }

        public void Start()
        {
            CommonHelper.writelog("Thread start..");
            object stateCheckBugs = new object();
            ThreadPool.RegisterWaitForSingleObject(waitCheckBugs, new WaitOrTimerCallback(RefreshCheck), stateCheckBugs, Convert.ToInt32(CommonHelper.GetConfigValue("Timer_Interval")), false);
            waitCheckBugs.Set();
        }
    }
}


